<!--
 * @Author: anonymous
 * @Date: 2022-05-13 12:32:49
 * @LastEditors: anonymous
 * @LastEditTime: 2022-05-17 00:55:44
 * @FilePath: /vue3-teap/src/components/UserRole.vue
 * @Description:
-->
<template>
  <el-row :gutter="10">
    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
      <el-input v-model="search.searchUserId" @keydown.enter="searchUserIdFn" placeholder="搜索用户ID"
        clearable class="input-with-select">
        <template #append>
          <el-button @click="searchUserIdFn">
            <i class="fa fa-search" aria-hidden="true"></i>
          </el-button>
        </template>
      </el-input>
    </el-col>
    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
      <el-select v-model="search.searchRoleId" multiple placeholder="搜索角色" style="width: 360px">
        <el-option v-for="item in store.role" :key="item.roleId" :label="item.roleName"
          :value="item.roleId"></el-option>
      </el-select>
      <el-button @click="searchRoleIdFn">
        <i class="fa fa-search" aria-hidden="true"></i>
      </el-button>
    </el-col>
  </el-row>
  <el-row :gutter="10">
    <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
      <el-select v-model="search.searchEnabled" clearable placeholder="搜索状态" style="width: 360px">
        <el-option v-for="(item, index) in Object.values(enabledText)" :key="index"
          :label="item.label" :value="item.value"></el-option>
      </el-select>
      <el-button @click="searchEnabledFn">
        <i class="fa fa-search" aria-hidden="true"></i>
      </el-button>
    </el-col>
  </el-row>
  <el-divider />
  <el-table :data="userRoleList" class="tableStyle" style="width: 100%">
    <el-table-column type="expand">
      <template #default="props">
        <el-descriptions class="margin-top" title="角色权限" :column="2" size="small" border>
          <el-descriptions-item>
            <template #label>
              <div class="cell-item">
                <i class="fa fa-id-card-o" aria-hidden="true"></i>
                用户ID
              </div>
            </template>
            {{ props.row.userId }}
          </el-descriptions-item>
          <el-descriptions-item>
            <template #label>
              <div class="cell-item">
                <i class="fa fa-id-badge" aria-hidden="true"></i>
                角色ID
              </div>
            </template>
            {{ props.row.roleId }}
          </el-descriptions-item>
          <el-descriptions-item>
            <template #label>
              <div class="cell-item">
                <i class="fa fa-key" aria-hidden="true"></i>
                角色权限
              </div>
            </template>
            <el-tag v-for="item in props.row.permissionEntities" :key="item.permId"
              :label="item.permName" type="info" class="mx-1" effect="dark">
              {{ item.permName }}
            </el-tag>
            <el-button type="primary" size="small" @click="openDialog(props.row)">
              <i class="fa fa-pencil-square-o" aria-hidden="true"></i>&nbsp;修改权限
            </el-button>
          </el-descriptions-item>
        </el-descriptions>
      </template>
    </el-table-column>
    <el-table-column label="姓名(昵称)">
      <template #default="scope">
        {{scope.row.userNickname}}{{scope.row.workerName}}{{scope.row.name}}
      </template>
    </el-table-column>
    <el-table-column prop="roleName" label="角色" />
    <el-table-column prop="enabled" label="状态">
      <template #default="scope">
        <el-tag class="ml-2" effect="dark" :type="enabledText[scope.row.enabled]['type']">
          {{enabledText[scope.row.enabled]['label']}}
        </el-tag>
      </template>
    </el-table-column>
    <el-table-column fixed="right" label="操作" width="120">
      <template #default="scope">
        <div class="enabledButton enabledButton_error" v-if="scope.row.enabled">
          <button @click="execEnabledRole(scope.row)">
            <i class="fa fa-unlock-alt" aria-hidden="true"></i>禁权
          </button>
        </div>
        <div class="enabledButton enabledButton_success" v-else>
          <button @click="execOpenRole(scope.row)">
            <i class="fa fa-unlock" aria-hidden="true"></i>解禁
          </button>
        </div>
      </template>
    </el-table-column>
  </el-table>
  <div class="pagination">
    <el-pagination @size-change="val=>pagination.pageSize = val" @current-change="currentPageChange"
      :current-page="pagination.currentPage" :pager-count="pagination.pagerCount"
      :page-sizes="pagination.pageSizes" :page-size="pagination.pageSize"
      layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" background>
    </el-pagination>
  </div>
  <el-dialog v-model="dialog.dialogVisible" title="权限修改" :close-on-click-modal="false">
    <el-select v-model="dialog.editPermission" multiple style="width:100%"
      placeholder="Please select permission">
      <el-option v-for="item in store.permission" :key="item.permId" :label="item.permName"
        :value="item.permId" />
    </el-select>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialog.dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmEditPermission">修改</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang='ts'>
import { defineComponent, reactive, toRaw, toRefs } from 'vue'
import { editUserPermission, pullPermission, pullUserRole, queryByEnabled, queryByURoleId, queryByUserId, toggleRole } from '@/plugins/request/http'
import { responseEnum, responseUtil } from '@/plugins/request/responseUtil'
import UserRoleData, { IResult, IUserRole, enabledText } from '@/model/main/layout/dynamicNav/PermissionPage/UserRole'
import { useStore } from '@/plugins/store/store'
import nProgress from 'nprogress'
import { ElMessage } from 'element-plus'
import _cloneDeep from 'lodash/cloneDeep'
import { IPermission } from '@/model/main/layout/dynamicNav/PermissionPage/PermissionManage'

export default defineComponent({
  name: 'UserRole',
  setup () {
    const store = useStore()
    const coreData = reactive(new UserRoleData())

    /**
     * @description: 后端获取用户角色关联信息
     * @param {*}
     * @return {*}
     */
    const execPullUserRole = async (val = 1) => {
      nProgress.start()
      const result = await (await pullUserRole(val, coreData.pagination.pageSize)).data as responseUtil<IResult>

      coreData.pagination.total = result.data?.total || 0

      let current = (val - 1) * coreData.pagination.pageSize

      if (!coreData.userRoleList) {
        coreData.userRoleList = new Array<IUserRole>(result.data.total)
      }
      result.data?.records.forEach(item => {
        coreData.userRoleList[current++] = item
      })
      nProgress.done()
      return result
    }
    execPullUserRole()

    /**
     * @description: 当缓存中不存在权限信息，则获取权限信息
     * @param {*}
     * @return {*}
     */
    const initPermission = async () => {
      if (!store.permission) {
        nProgress.start()
        store.permission = await (await pullPermission()).data.data
        nProgress.done()
      }
    }
    initPermission()

    /**
     * @description: 禁用用户
     * @param {*} row
     * @return {*}
     */
    const execEnabledRole = async (row: IUserRole) => {
      const isEnabled = confirm('你确定要禁用该用户吗?')
      if (!isEnabled) return
      nProgress.start()
      const result = await (await toggleRole(row)).data as responseUtil
      if (result.code === responseEnum.OK) {
        row.enabled = false
        ElMessage.success((row.userNickname || row.workerName || row.name) + '已被禁权')
      } else {
        ElMessage.error(result.msg)
      }
      nProgress.done()
    }

    /**
     * @description: 开启用户
     * @param {*} row
     * @return {*}
     */
    const execOpenRole = async (row: IUserRole) => {
      const isEnabled = confirm('你确定要解禁该用户吗?')
      if (!isEnabled) return
      nProgress.start()
      const result = await (await toggleRole(row)).data as responseUtil
      if (result.code === responseEnum.OK) {
        row.enabled = true
        ElMessage.success((row.userNickname || row.workerName || row.name) + '已被解禁')
      } else {
        ElMessage.error(result.msg)
      }
      nProgress.done()
    }

    /**
     * @description: 当前页变更
     * @param {*} val
     * @return {*}
     */
    const currentPageChange = (val: number) => {
      if (coreData.userRoleList[(val - 1) * coreData.pagination.pageSize]) {
        coreData.pagination.currentPage = val
      } else {
        execPullUserRole(val).then(() => {
          coreData.pagination.currentPage = val
        })
      }
    }

    /**
     * @description: 搜索用户ID，根据 UserId 查询用户角色关联信息
     * @param {*} ev
     * @return {*}
     */
    const searchUserIdFn = async (ev: Event) => {
      const searchUserId = toRaw(coreData.search.searchUserId)
      if (searchUserId.trim() === '') {
        const code = await (await execPullUserRole()).code
        if (code === responseEnum.OK) {
          ElMessage.success('查询成功')
        } else {
          ElMessage.error('查询失败')
        }
        (ev.target as HTMLInputElement).blur()
        return
      }
      nProgress.start()
      const result = await (await queryByUserId(searchUserId)).data as responseUtil<IUserRole[]>
      if (result.code === responseEnum.OK) {
        coreData.userRoleList = result.data || []
        ElMessage.success('查询成功')
      } else {
        ElMessage.error('查询失败')
      }
      (ev.target as HTMLInputElement).blur()
      nProgress.done()
    }

    /**
     * @description: 搜索角色。根据 RoleId 查询用户角色关联信息
     * @param {*}
     * @return {*}
     */
    const searchRoleIdFn = async () => {
      const searchRoleId = toRaw(coreData.search.searchRoleId)
      if (searchRoleId.length === 0) {
        const code = await (await execPullUserRole()).code
        if (code === responseEnum.OK) {
          ElMessage.success('查询成功')
        } else {
          ElMessage.error('查询失败')
        }
        return
      }
      nProgress.start()
      const result = await (await queryByURoleId(searchRoleId)).data as responseUtil<IUserRole[]>
      if (result.code === responseEnum.OK) {
        coreData.userRoleList = result.data || []
        ElMessage.success('查询成功')
      } else {
        ElMessage.error('查询失败')
      }
      nProgress.done()
    }

    /**
     * @description: 搜索状态。根据 Enabled 查询用户角色关联信息
     * @param {*}
     * @return {*}
     */
    const searchEnabledFn = async () => {
      const searchEnabled = toRaw(coreData.search.searchEnabled)
      if (typeof searchEnabled !== 'boolean' && searchEnabled.trim() === '') {
        const code = await (await execPullUserRole()).code
        if (code === responseEnum.OK) {
          ElMessage.success('查询成功')
        } else {
          ElMessage.error('查询失败')
        }
        return
      }
      nProgress.start()
      const result = await (await queryByEnabled(searchEnabled as unknown as boolean)).data as responseUtil<IUserRole[]>
      if (result.code === responseEnum.OK) {
        coreData.userRoleList = result.data || []
        ElMessage.success('查询成功')
      } else {
        ElMessage.error('查询失败')
      }
      nProgress.done()
    }

    const openDialog = (row: IUserRole) => {
      const data = _cloneDeep(row)
      coreData.dialog.userRole = data
      coreData.dialog.editPermission = data.permissionEntities.map(item => item.permId)
      coreData.dialog.dialogVisible = true
    }

    const confirmEditPermission = async () => {
      const obj = {
        userId: coreData.dialog.userRole.userId,
        editPermission: coreData.dialog.editPermission
      }
      const result = await (await editUserPermission(obj)).data as responseUtil
      if (result.code !== 43000) {
        ElMessage.error(result.msg)
        return
      }
      coreData.userRoleList.some(item => {
        if (item.userId === obj.userId) {
          item.permissionEntities.length = 0
          coreData.dialog.editPermission.forEach(permId => {
            item.permissionEntities.push(store.permission.find(perm => perm.permId === permId) as IPermission)
          })
          return true
        }
        return false
      })
      ElMessage.success(result.msg)
      coreData.dialog.dialogVisible = false
    }

    return {
      ...toRefs(coreData),
      execEnabledRole,
      execOpenRole,
      currentPageChange,
      store,
      searchUserIdFn,
      searchRoleIdFn,
      searchEnabledFn,
      enabledText,
      openDialog,
      confirmEditPermission
    }
  }
})
</script>

<style lang='scss' scoped>
@import '@/assets/scss/enableButton.scss';

.el-row {
  .el-col {
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
  }
}

.tableStyle {
  .el-tag {
    font-weight: bold;
  }
}

.pagination {
  display: flex;
  justify-content: center;
  margin-top: 1rem;
  align-items: center;
}
</style>

